package pobidz;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

public class Filtration {

	
	private ComplexImage img;
	private int[][] filter;
	private int imageWidth;
	private int imageHeight;
	private BufferedImage image;
	
	public Filtration(BufferedImage image, ComplexImage img)
	{
		this.image = image;
		this.img = img;
		this.imageWidth = img.getPointsR().length;
		this.imageHeight = img.getPointsR()[0].length;
		filter = new int[this.imageWidth][this.imageHeight];
	}
	
	
	public ComplexImage lowPassFilter(int r)
	{
		for (int i=0; i<filter.length; i++)
		{
			for (int j=0; j<filter[0].length; j++)
			{
				if (Math.sqrt(Math.pow(imageWidth/2-i,2)+Math.pow(imageHeight/2-j,2)) <= r)
				{
					//filter[i][j] = 1;
					//img[i][j].setReal(img[i][j].getReal())
				}
				else
				{
					filter[i][j] = 0;
					img.getPointsR()[i][j].setReal(0);
					img.getPointsR()[i][j].setImaginary(0);
					img.getPointsG()[i][j].setReal(0);
					img.getPointsG()[i][j].setImaginary(0);
					img.getPointsB()[i][j].setReal(0);
					img.getPointsB()[i][j].setImaginary(0);
				}
			}
		}
		
		
		
		return new ComplexImage(imageWidth, imageHeight, img.getPointsR(),
				img.getPointsG(), img.getPointsB());
	}
	
	public ComplexImage highPassFilter(int r)
	{
		for (int i=0; i<filter.length; i++)
		{
			for (int j=0; j<filter[0].length; j++)
			{
				if (Math.sqrt(Math.pow(imageWidth/2-i,2)+Math.pow(imageHeight/2-j,2)) <= r)
				{
					//filter[i][j] = 1;
					//img[i][j].setReal(img[i][j].getReal())
					img.getPointsR()[i][j].setReal(0);
					img.getPointsR()[i][j].setImaginary(0);
					img.getPointsG()[i][j].setReal(0);
					img.getPointsG()[i][j].setImaginary(0);
					img.getPointsB()[i][j].setReal(0);
					img.getPointsB()[i][j].setImaginary(0);
				}
				else
				{

				}
			}
		}
		
		
		
		return new ComplexImage(imageWidth, imageHeight, img.getPointsR(),
				img.getPointsG(), img.getPointsB());
	}
	
	
	public ComplexImage bandPassFilter(int r1, int r2)
	{
		for (int i=0; i<filter.length; i++)
		{
			for (int j=0; j<filter[0].length; j++)
			{ 
				double val = Math.sqrt(Math.pow(imageWidth/2-i,2)+Math.pow(imageHeight/2-j,2));

				if (val > r1 && val < r2)
				{

					img.getPointsR()[i][j].setReal(0);
					img.getPointsR()[i][j].setImaginary(0);
					img.getPointsG()[i][j].setReal(0);
					img.getPointsG()[i][j].setImaginary(0);
					img.getPointsB()[i][j].setReal(0);
					img.getPointsB()[i][j].setImaginary(0);
				}

			}
		}
		
		
		
		return new ComplexImage(imageWidth, imageHeight, img.getPointsR(),
				img.getPointsG(), img.getPointsB());
	}
	
	public ComplexImage bandStopFilter(int r1, int r2)
	{
		for (int i=0; i<filter.length; i++)
		{
			for (int j=0; j<filter[0].length; j++)
			{ 
				double val = Math.sqrt(Math.pow(imageWidth/2-i,2)+Math.pow(imageHeight/2-j,2));

				if (val > r1 && val < r2)
				{

				}
				else
				{
					img.getPointsR()[i][j].setReal(0);
					img.getPointsR()[i][j].setImaginary(0);
					img.getPointsG()[i][j].setReal(0);
					img.getPointsG()[i][j].setImaginary(0);
					img.getPointsB()[i][j].setReal(0);
					img.getPointsB()[i][j].setImaginary(0);
				}

			}
		}
		
		
		
		return new ComplexImage(imageWidth, imageHeight, img.getPointsR(),
				img.getPointsG(), img.getPointsB());
	}
	
	public ComplexImage edgeDetectionFilter(int r, int angle, int width, BufferedImage mask)
	{//image = aaa;
		for (int i=0; i<filter.length; i++)
		{
			for (int j=0; j<filter[0].length; j++)
			{
				if (Math.sqrt(Math.pow(imageWidth/2-i,2)+Math.pow(imageHeight/2-j,2)) <= r)
				{
					filter[i][j] = 0;
					//img[i][j].setReal(img[i][j].getReal())
//					img[i][j].setReal(0);
//					img[i][j].setImaginary(0);
//					img[i][j].setReal(0);
//					img[i][j].setImaginary(0);
					mask.setRGB(i, j, -16777722);
				}
				else
				{
					filter[i][j] = 1;
					mask.setRGB(i, j, -1);
				}
			}
		}
		
		int[][] filter2 = new int[filter.length][filter[0].length];
		double a = Math.tan(Math.toRadians(angle+width));
		double a2 = Math.tan(Math.toRadians(angle-width));
		for (int x=0; x<filter2.length; x++)
		{
			for (int y=0; y<filter2.length; y++)
			{
				filter2[x][y] = 0;
				mask.setRGB(x,y,-16666666);
			}
		}
		
		for (int x=0; x<filter2.length; x++)
		{
			double y = (x-(imageWidth/2))*a;
			double y2 = (x-(imageWidth/2))*a2;
//			System.out.println(a);
//			System.out.println("dla x " + x + " a dla y " + (int)y);

			mask.setRGB(x,(imageWidth/2-1)-(int)y,-1);
			mask.setRGB(x,(imageWidth/2-1)-(int)y2,-1);
			
			if (x-(imageWidth/2) < 0)
			{
				for (int i=(imageWidth/2-1)-(int)y; i>(imageWidth/2-1)-(int)y2; i--)
				{
					filter2[x][i] = 1;
					filter2[x][i] = 1;
					mask.setRGB(x,i,-1);
				}
			}
			else
			{
				for (int i=(imageWidth/2-1)-(int)y; i<(imageWidth/2-1)-(int)y2; i++)
				{
					filter2[x][i] = 1;
					filter2[x][i] = 1;
					mask.setRGB(x,i,-1);
				}
			}
			
		}
		
		for (int i=0; i<filter.length; i++)
		{
			for (int j=0; j<filter[0].length; j++)
			{
				filter[i][j] *= filter2[i][j];
				mask.setRGB(i,j,-167772422*filter[i][j]);
//				img[i][j].setReal(filter[i][j]*img[i][j].getReal());
//				img[i][j].setImaginary(filter[i][j]*img[i][j].getImaginary());
				
				
				img.getPointsR()[i][j].setReal(filter[i][j]*img.getPointsR()[i][j].getReal());
				img.getPointsR()[i][j].setImaginary(filter[i][j]*img.getPointsR()[i][j].getImaginary());
				img.getPointsG()[i][j].setReal(filter[i][j]*img.getPointsG()[i][j].getReal());
				img.getPointsG()[i][j].setImaginary(filter[i][j]*img.getPointsG()[i][j].getImaginary());
				img.getPointsB()[i][j].setReal(filter[i][j]*img.getPointsB()[i][j].getReal());
				img.getPointsB()[i][j].setImaginary(filter[i][j]*img.getPointsB()[i][j].getImaginary());
				
			}
		}
		
		//return image;
		return new ComplexImage(imageWidth, imageHeight, img.getPointsR(),
				img.getPointsG(), img.getPointsB());
	}
	
	
	
	
	public ComplexImage phaseModificationFilter(BufferedImage image, ComplexImage complexImage, int k, int l)
	{
		//ComplexImage img = complexImage;

		List<UnprocessedColor> unp = new ArrayList<UnprocessedColor>();
		
		for (int n=0; n<complexImage.getSizeY(); n++)
		{
			for (int m=0; m<complexImage.getSizeX(); m++)
			{
				complexImage=phaseModificationFilterValue(complexImage,m,n,k,l);
                                /*
                                if(complexImage.getPointsG()[n][m].getReal()<0){
                                complexImage.getPointsG()[n][m].setReal(-complexImage.getPointsG()[n][m].getReal());
                                
                                }
                                 if(complexImage.getPointsB()[n][m].getReal()<0){
                                complexImage.getPointsB()[n][m].setReal(-complexImage.getPointsB()[n][m].getReal());
                                
                                }
                                  if(complexImage.getPointsR()[n][m].getReal()<0){
                                complexImage.getPointsR()[n][m].setReal(-complexImage.getPointsR()[n][m].getReal());
                                
                                }
                                * */
                                   if(complexImage.getPointsR()[n][m].getReal()>255){
                                complexImage.getPointsR()[n][m].setReal(255);
                                
                                }
                                    if(complexImage.getPointsG()[n][m].getReal()>255){
                                complexImage.getPointsG()[n][m].setReal(255);
                                
                                }
                                     if(complexImage.getPointsB()[n][m].getReal()>255){
                                complexImage.getPointsB()[n][m].setReal(255);
                                
                                }
                                     
                                         if(complexImage.getPointsG()[n][m].getReal()<0){
                                complexImage.getPointsG()[n][m].setReal(0);
                                
                                }
                                 if(complexImage.getPointsB()[n][m].getReal()<0){
                                complexImage.getPointsB()[n][m].setReal(0);
                                
                                }
                                  if(complexImage.getPointsR()[n][m].getReal()<0){
                                complexImage.getPointsR()[n][m].setReal(0);
                                
                                }
                                //     System.out.println("B "+complexImage.getPointsB()[n][m].getReal());
                              //        System.out.println("G "+complexImage.getPointsG()[n][m].getReal());
                              //         System.out.println("R "+complexImage.getPointsR()[n][m].getReal());
				unp.add(new UnprocessedColor((int)complexImage.getPointsR()[n][m].getReal(),
						(int)complexImage.getPointsG()[n][m].getReal(),
						(int)complexImage.getPointsB()[n][m].getReal()));
			
			}
		}
		
		return complexImage;
	}
	
	
	private ComplexImage phaseModificationFilterValue(ComplexImage complexImage, int n, int m, double k, double l)
	{


		
		double arg = (((-n*k*2.0*Math.PI)/ imageWidth) 
					+ ((-m*l*2.0*Math.PI)/ imageHeight)
					+ (k + l)*Math.PI);
		
		double real = Math.cos(arg);
		double imaginary = Math.sin(arg);

		
		int valueR = (int)(complexImage.getPointsR()[m][n].getReal() * real - complexImage.getPointsR()[m][n].getImaginary() * imaginary);
		int valueI = (int)(complexImage.getPointsR()[m][n].getImaginary() * real + complexImage.getPointsR()[m][n].getReal() * imaginary);
		
		complexImage.getPointsR()[m][n].setReal(valueR);
		complexImage.getPointsR()[m][n].setImaginary(valueI);
		
		int valueRR = (int)(complexImage.getPointsG()[m][n].getReal() * real - complexImage.getPointsG()[m][n].getImaginary() * imaginary);
		int valueII = (int)(complexImage.getPointsG()[m][n].getImaginary() * real + complexImage.getPointsG()[m][n].getReal() * imaginary);
		
		complexImage.getPointsG()[m][n].setReal(valueRR);
		complexImage.getPointsG()[m][n].setImaginary(valueII);
		
		int valueRRR = (int)(complexImage.getPointsB()[m][n].getReal() * real - complexImage.getPointsB()[m][n].getImaginary() * imaginary);
		int valueIII = (int)(complexImage.getPointsB()[m][n].getImaginary() * real + complexImage.getPointsB()[m][n].getReal() * imaginary);
		
		complexImage.getPointsB()[m][n].setReal(valueRRR);
		complexImage.getPointsB()[m][n].setImaginary(valueIII);
        return complexImage;

	}
	
	
}
